`
https://leetcode.cn/problems/cracking-the-safe/
`

/**
 * @param {number} n
 * @param {number} k
 * @return {string}
 */
var crackSafe = function (n, k) {
  // 欧拉路径问题，数据范围较小不需要构建图结构，直接计算即可
  if (n === 1) {
    // 密码只有一位，直接返回对应的截取部分即可
    return '0123456789'.slice(0, k)
  }

  // 记录访问过的边，值类似于 '0->10'
  const visited = new Set()
  // 记录后序遍历结果
  const postOrder = []
  const base = 10 ** (n - 1)

  dfs(0)

  postOrder.reverse()

  function dfs(node) {
    for (let i = 0; i < k; i++) {
      const nextNode = (node * 10 + i) % base
      const edge = `${node}->${nextNode}`
      if (!visited.has(edge)) {
        visited.add(edge)
        dfs(nextNode)
      }
    }
    postOrder.push(node)
  }

  let res = '0'.repeat(n - 1)
  for (let i = 0; i < postOrder.length - 1; i++) {
    const nextNode = postOrder[i + 1]
    // nextNode 的个位就是边的值
    res += nextNode % 10
  }
  return res
};